package concurrent_util;

import sun.reflect.generics.tree.Tree;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalField;
import java.util.*;
import java.util.function.BiFunction;

/**
 * @author: yangwk
 * @date: 2023/10/7
 * @description:
 **/
public class WindowLimit {
    // 单位10秒
    private int windowSize = 10;
    // 最大流量
    private int maxFlow = 9;
    TreeMap<String, Integer> visitCount = new TreeMap<>(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o2.compareTo(o1);
        }
    });
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public boolean canPass() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime begin = now.minusSeconds(windowSize);
        int sum = 1;
        for (LocalDateTime i = begin; i.isBefore(now); i=i.plusSeconds(1)) {
            if (visitCount.containsKey(i.format(dateTimeFormatter))) {
                sum += visitCount.get(i.format(dateTimeFormatter));
            }
        }
        if (sum > maxFlow) {
            System.out.println("访问失败");
            return false;
        }
        visitCount.compute(now.format(dateTimeFormatter), (key, integer) -> {
            if (integer == null) {
                return 1;
            }
            return integer + 1;
        });
        SortedMap<String, Integer> stringIntegerSortedMap = visitCount.tailMap(begin.format(dateTimeFormatter));
        for (Map.Entry<String, Integer> stringIntegerEntry : stringIntegerSortedMap.entrySet()) {
            System.out.println("过期访问：" + stringIntegerEntry.getKey());
        }
        System.out.println("-------------");
        return true;
    }

    public static void main(String[] args) throws InterruptedException {
        WindowLimit limit = new WindowLimit();
        for (int i = 0; i < 100; i++) {
            Thread.sleep(1*1000);
            limit.canPass();
        }
    }
}
